package com.dekun.workhard.config.security;


import com.dekun.workhard.config.security.token.MobilePasswordAuthenticationToken;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;


@Slf4j
@Data
public class MobilePasswordProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    private PasswordEncoder passwordEncoder;

    public MobilePasswordProvider() {
    }


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String userName =  authentication.getName();
        Assert.hasText(userName,"手机号不能为空");

        UserDetails user = null;
        try{
            user = userDetailsService.loadUserByUsername(userName);
        }catch (UsernameNotFoundException ex) {
           throw new UsernameNotFoundException("用戶不存在!");
        }

        if (!user.isAccountNonLocked()) {
            throw new LockedException("账号被锁定!");
        }
        if (!user.isEnabled()) {
            throw new DisabledException("账号不可用!");
        }
        if (!user.isAccountNonExpired()) {
            throw new AccountExpiredException("账号已过期");
        }

        String presentedPassword = authentication.getCredentials().toString();
        if (!this.passwordEncoder.matches(presentedPassword, user.getPassword())) {
            throw new BadCredentialsException("密码错误");
        }

        MobilePasswordAuthenticationToken result = new MobilePasswordAuthenticationToken(authentication.getName(),
                authentication.getCredentials(), user.getAuthorities());
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (MobilePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
}
